package com.alex.zookeeper.service.configuration;

import lombok.extern.slf4j.Slf4j;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.CountDownLatch;

/**
 * 存储key-value键值对
 */
@Slf4j
public class ActiveKeyValueStore {

    private static final Charset CHARSET = StandardCharsets.UTF_8;

    private ZooKeeper zooKeeper;

    /**
     * Node节点不存在的时候, 创建Node节点;
     * Node节点存在的时候, 更新Node数据.
     */
    public void write(String path, String value) throws KeeperException, InterruptedException {
        Stat stat = zooKeeper.exists(path, false);
        if (stat == null) {
            zooKeeper.create(path, value.getBytes(CHARSET), ZooDefs.Ids.OPEN_ACL_UNSAFE,
                    CreateMode.PERSISTENT);
        } else {
            zooKeeper.setData(path, value.getBytes(), -1);
        }
    }

    /**
     * 连接ZK
     */
    public void connection() throws IOException, InterruptedException {
        CountDownLatch latch = new CountDownLatch(1);
        // zookeeper创建连接是异步的
        // sessionTimeout:session等待时间, 单位是毫秒
        // watch响应事件触发器
        zooKeeper = new ZooKeeper("127.0.0.1:2181", 30000, watchedEvent -> {
            log.info("event: {}", watchedEvent);
            if (Watcher.Event.KeeperState.SyncConnected == watchedEvent.getState()) {
                log.info("Connection...");
                latch.countDown();
            }

            if (Watcher.Event.KeeperState.Closed == watchedEvent.getState()) {
                log.info("Closed...");
            }
        });

        latch.await();
    }

    /**
     * 读取数据
     */
    public String read(String path, Watcher watcher) throws KeeperException, InterruptedException {
        byte[] data = zooKeeper.getData(path, watcher, null);
        return new String(data);
    }
}
